home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / cvs-1_3.lha / cvs-1.3 / src / checkout.c < prev    next >
C/C++ Source or Header  |  1992-04-09  |  19KB  |  719 lines

  1. /*
  2.  * Copyright (c) 1992, Brian Berliner and Jeff Polk
  3.  * Copyright (c) 1989-1992, Brian Berliner
  4.  * 
  5.  * You may distribute under the terms of the GNU General Public License as
  6.  * specified in the README file that comes with the CVS 1.3 kit.
  7.  * 
  8.  * Create Version
  9.  * 
  10.  * "checkout" creates a "version" of an RCS repository.  This version is owned
  11.  * totally by the user and is actually an independent copy, to be dealt with
  12.  * as seen fit.  Once "checkout" has been called in a given directory, it
  13.  * never needs to be called again.  The user can keep up-to-date by calling
  14.  * "update" when he feels like it; this will supply him with a merge of his
  15.  * own modifications and the changes made in the RCS original.  See "update"
  16.  * for details.
  17.  * 
  18.  * "checkout" can be given a list of directories or files to be updated and in
  19.  * the case of a directory, will recursivley create any sub-directories that
  20.  * exist in the repository.
  21.  * 
  22.  * When the user is satisfied with his own modifications, the present version
  23.  * can be committed by "commit"; this keeps the present version in tact,
  24.  * usually.
  25.  * 
  26.  * The call is cvs checkout [options] <module-name>...
  27.  * 
  28.  * "checkout" creates a directory ./CVS, in which it keeps its administration,
  29.  * in two files, Repository and Entries. The first contains the name of the
  30.  * repository.  The second contains one line for each registered file,
  31.  * consisting of the version number it derives from, its time stamp at
  32.  * derivation time and its name.  Both files are normal files and can be
  33.  * edited by the user, if necessary (when the repository is moved, e.g.)
  34.  */
  35.  
  36. #include "cvs.h"
  37.  
  38. #ifndef lint
  39. static char rcsid[] = "@(#)checkout.c 1.67 92/04/10";
  40. #endif
  41.  
  42. #if __STDC__
  43. static char *findslash (char *start, char *p);
  44. static int build_dirs_and_chdir (char *dir, char *prepath, char *realdir,
  45.                  int sticky);
  46. static int checkout_proc (int *pargc, char *argv[], char *where,
  47.                   char *mwhere, char *mfile, int shorten,
  48.                   int local_specified, char *omodule,
  49.                   char *msg);
  50. #else
  51. static int checkout_proc ();
  52. static char *findslash ();
  53. static int build_dirs_and_chdir ();
  54. #endif                /* __STDC__ */
  55.  
  56. static char *checkout_usage[] =
  57. {
  58.     "Usage:\n  %s %s [-ANPQcflnpqs] [-r rev | -D date] [-d dir] [-k kopt] modules...\n",
  59.     "\t-A\tReset any sticky tags/date/kopts.\n",
  60.     "\t-N\tDon't shorten module paths if -d specified.\n",
  61.     "\t-P\tPrune empty directories.\n",
  62.     "\t-Q\tReally quiet.\n",
  63.     "\t-c\t\"cat\" the module database.\n",
  64.     "\t-f\tForce a head revision match if tag/date not found.\n",
  65.     "\t-l\tLocal directory only, not recursive\n",
  66.     "\t-n\tDo not run module program (if any).\n",
  67.     "\t-p\tCheck out files to standard output.\n",
  68.     "\t-q\tSomewhat quiet.\n",
  69.     "\t-s\tLike -c, but include module status.\n",
  70.     "\t-r rev\tCheck out revision or tag. (implies -P)\n",
  71.     "\t-D date\tCheck out revisions as of date. (implies -P)\n",
  72.     "\t-d dir\tCheck out into dir instead of module name.\n",
  73.     "\t-k kopt\tUse RCS kopt -k option on checkout.\n",
  74.     "\t-j rev\tMerge in changes made between current revision and rev.\n",
  75.     NULL
  76. };
  77.  
  78. static char *export_usage[] =
  79. {
  80.     "Usage: %s %s [-NPQflnq] [-r rev | -D date] [-d dir] module...\n",
  81.     "\t-N\tDon't shorten module paths if -d specified.\n",
  82.     "\t-Q\tReally quiet.\n",
  83.     "\t-f\tForce a head revision match if tag/date not found.\n",
  84.     "\t-l\tLocal directory only, not recursive\n",
  85.     "\t-n\tDo not run module program (if any).\n",
  86.     "\t-q\tSomewhat quiet.\n",
  87.     "\t-r rev\tCheck out revision or tag. (implies -P)\n",
  88.     "\t-D date\tCheck out revisions as of date. (implies -P)\n",
  89.     "\t-d dir\tCheck out into dir instead of module name.\n",
  90.     NULL
  91. };
  92.  
  93. static int checkout_prune_dirs;
  94. static int force_tag_match = 1;
  95. static int pipeout;
  96. static int aflag;
  97. static char *options = NULL;
  98. static char *tag = NULL;
  99. static char *date = NULL;
  100. static char *join_rev1 = NULL;
  101. static char *join_rev2 = NULL;
  102. static char *preload_update_dir = NULL;
  103.  
  104. int
  105. checkout (argc, argv)
  106.     int argc;
  107.     char *argv[];
  108. {
  109.     register int i;
  110.     int c;
  111.     DBM *db;
  112.     int cat = 0, err = 0, status = 0;
  113.     int run_module_prog = 1;
  114.     int local = 0;
  115.     int shorten = -1;
  116.     char *where = NULL;
  117.     char *valid_options, **valid_usage;
  118.  
  119.     /*
  120.      * A smaller subset of options are allowed for the export command, which
  121.      * is essentially like checkout, except that it hard-codes certain
  122.      * options to be on (like -kv) and takes care to remove the CVS directory
  123.      * when it has done its duty
  124.      */
  125.     if (strcmp (command_name, "export") == 0)
  126.     {
  127.     valid_options = "Nnd:flRQqr:D:";
  128.     valid_usage = export_usage;
  129.     }
  130.     else
  131.     {
  132.     valid_options = "ANnk:d:flRpQqcsr:D:j:P";
  133.     valid_usage = checkout_usage;
  134.     }
  135.  
  136.     if (argc == -1)
  137.     usage (valid_usage);
  138.  
  139.     ign_setup ();
  140.  
  141.     optind = 1;
  142.     while ((c = gnu_getopt (argc, argv, valid_options)) != -1)
  143.     {
  144.     switch (c)
  145.     {
  146.         case 'A':
  147.         aflag = 1;
  148.         break;
  149.         case 'N':
  150.         shorten = 0;
  151.         break;
  152.         case 'k':
  153.         if (options)
  154.             free (options);
  155.         options = RCS_check_kflag (optarg);
  156.         break;
  157.         case 'n':
  158.         run_module_prog = 0;
  159.         break;
  160.         case 'Q':
  161.         really_quiet = 1;
  162.         /* FALL THROUGH */
  163.         case 'q':
  164.         quiet = 1;
  165.         break;
  166.         case 'l':
  167.         local = 1;
  168.         break;
  169.         case 'R':
  170.         local = 0;
  171.         break;
  172.         case 'P':
  173.         checkout_prune_dirs = 1;
  174.         break;
  175.         case 'p':
  176.         pipeout = 1;
  177.         run_module_prog = 0;    /* don't run module prog when piping */
  178.         noexec = 1;        /* so no locks will be created */
  179.         break;
  180.         case 'c':
  181.         cat = 1;
  182.         break;
  183.         case 'd':
  184.         where = optarg;
  185.         if (shorten == -1)
  186.             shorten = 1;
  187.         break;
  188.         case 's':
  189.         status = 1;
  190.         break;
  191.         case 'f':
  192.         force_tag_match = 0;
  193.         break;
  194.         case 'r':
  195.         tag = optarg;
  196.         checkout_prune_dirs = 1;
  197.         break;
  198.         case 'D':
  199.         date = Make_Date (optarg);
  200.         checkout_prune_dirs = 1;
  201.         break;
  202.         case 'j':
  203.         if (join_rev2)
  204.             error (1, 0, "only two -j options can be specified");
  205.         if (join_rev1)
  206.             join_rev2 = optarg;
  207.         else
  208.             join_rev1 = optarg;
  209.         break;
  210.         case '?':
  211.         default:
  212.         usage (valid_usage);
  213.         break;
  214.     }
  215.     }
  216.     argc -= optind;
  217.     argv += optind;
  218.  
  219.     if (shorten == -1)
  220.     shorten = 0;
  221.  
  222.     if ((!(cat + status) && argc == 0) || ((cat + status) && argc != 0)
  223.     || (tag && date))
  224.     usage (valid_usage);
  225.  
  226.     if (where && pipeout)
  227.     error (1, 0, "-d and -p are mutually exclusive");
  228.  
  229.     if (strcmp (command_name, "export") == 0)
  230.     {
  231.     if (!tag && !date)
  232.     {
  233.         error (0, 0, "must specify a tag or date");
  234.         usage (valid_usage);
  235.     }
  236.     if (tag && isdigit (tag[0]))
  237.         error (1, 0, "tag `%s' must be a symbolic tag", tag);
  238.     options = RCS_check_kflag ("v");/* -kv must be on */
  239.     }
  240.  
  241.     if (cat || status)
  242.     {
  243.     cat_module (status);
  244.     return (0);
  245.     }
  246.     db = open_module ();
  247.  
  248.     /*
  249.      * if we have more than one argument and where was specified, we make the
  250.      * where, cd into it, and try to shorten names as much as possible.
  251.      * Otherwise, we pass the where as a single argument to do_module.
  252.      */
  253.     if (argc > 1 && where != NULL)
  254.     {
  255.     char repository[PATH_MAX];
  256.  
  257.     (void) mkdir (where, 0777);
  258.     if (chdir (where) < 0)
  259.         error (1, errno, "cannot chdir to %s", where);
  260.     preload_update_dir = xstrdup (where);
  261.     where = (char *) NULL;
  262.     if (!isfile (CVSADM) && !isfile (OCVSADM))
  263.     {
  264.         (void) sprintf (repository, "%s/%s", CVSroot, CVSNULLREPOS);
  265.         if (!isfile (repository))
  266.         (void) mkdir (repository, 0777);
  267.         Create_Admin (".", repository, (char *) NULL, (char *) NULL);
  268.         if (!noexec)
  269.         {
  270.         FILE *fp;
  271.  
  272.         fp = open_file (CVSADM_ENTSTAT, "w+");
  273.         if (fclose(fp) == EOF)
  274.             error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
  275.         }
  276.     }
  277.     }
  278.  
  279.     /*
  280.      * if where was specified (-d) and we have not taken care of it already
  281.      * with the multiple arg stuff, and it was not a simple directory name
  282.      * but rather a path, we strip off everything but the last component and
  283.      * attempt to cd to the indicated place.  where then becomes simply the
  284.      * last component
  285.      */
  286.     if (where != NULL && index (where, '/') != NULL)
  287.     {
  288.     char *slash;
  289.  
  290.     slash = rindex (where, '/');
  291.     *slash = '\0';
  292.  
  293.     if (chdir (where) < 0)
  294.         error (1, errno, "cannot chdir to %s", where);
  295.  
  296.     preload_update_dir = xstrdup (where);
  297.  
  298.     where = slash + 1;
  299.     if (*where == '\0')
  300.         where = NULL;
  301.     }
  302.  
  303.     for (i = 0; i < argc; i++)
  304.     err += do_module (db, argv[i], CHECKOUT, "Updating", checkout_proc,
  305.               where, shorten, local, run_module_prog,
  306.               (char *) NULL);
  307.     close_module (db);
  308.     return (err);
  309. }
  310.  
  311. /*
  312.  * process_module calls us back here so we do the actual checkout stuff
  313.  */
  314. /* ARGSUSED */
  315. static int
  316. checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
  317.            local_specified, omodule, msg)
  318.     int *pargc;
  319.     char *argv[];
  320.     char *where;
  321.     char *mwhere;
  322.     char *mfile;
  323.     int shorten;
  324.     int local_specified;
  325.     char *omodule;
  326.     char *msg;
  327. {
  328.     int err = 0;
  329.     int which;
  330.     char *cp;
  331.     char *cp2;
  332.     char repository[PATH_MAX];
  333.     char xwhere[PATH_MAX];
  334.     char *oldupdate = NULL;
  335.     char *prepath;
  336.     char *realdirs;
  337.  
  338.     /*
  339.      * OK, so we're doing the checkout! Our args are as follows: 
  340.      *  argc,argv contain either dir or dir followed by a list of files 
  341.      *  where contains where to put it (if supplied by checkout) 
  342.      *  mwhere contains the module name or -d from module file 
  343.      *  mfile says do only that part of the module
  344.      *  shorten = TRUE says shorten as much as possible 
  345.      *  omodule is the original arg to do_module()
  346.      */
  347.  
  348.     /* set up the repository (maybe) for the bottom directory */
  349.     (void) sprintf (repository, "%s/%s", CVSroot, argv[0]);
  350.  
  351.     /* save the original value of preload_update_dir */
  352.     if (preload_update_dir != NULL)
  353.     oldupdate = xstrdup (preload_update_dir);
  354.  
  355.     /* fix up argv[] for the case of partial modules */
  356.     if (mfile != NULL)
  357.     {
  358.     char file[PATH_MAX];
  359.  
  360.     /* if mfile is really a path, straighten it out first */
  361.     if ((cp = rindex (mfile, '/')) != NULL)
  362.     {
  363.         *cp = 0;
  364.         (void) strcat (repository, "/");
  365.         (void) strcat (repository, mfile);
  366.  
  367.         /*
  368.          * Now we need to fill in the where correctly. if !shorten, tack
  369.          * the rest of the path onto where if where is filled in
  370.          * otherwise tack the rest of the path onto mwhere and make that
  371.          * the where
  372.          * 
  373.          * If shorten is enabled, we might use mwhere to set where if 
  374.          * nobody set it yet, so we'll need to setup mwhere as the last
  375.          * component of the path we are tacking onto repository
  376.          */
  377.         if (!shorten)
  378.         {
  379.         if (where != NULL)
  380.             (void) sprintf (xwhere, "%s/%s", where, mfile);
  381.         else
  382.             (void) sprintf (xwhere, "%s/%s", mwhere, mfile);
  383.         where = xwhere;
  384.         }
  385.         else
  386.         {
  387.         char *slash;
  388.  
  389.         if ((slash = rindex (mfile, '/')) != NULL)
  390.             mwhere = slash + 1;
  391.         else
  392.             mwhere = mfile;
  393.         }
  394.         mfile = cp + 1;
  395.     }
  396.  
  397.     (void) sprintf (file, "%s/%s", repository, mfile);
  398.     if (isdir (file))
  399.     {
  400.  
  401.         /*
  402.          * The portion of a module was a directory, so kludge up where to
  403.          * be the subdir, and fix up repository
  404.          */
  405.         (void) strcpy (repository, file);
  406.  
  407.         /*
  408.          * At this point, if shorten is not enabled, we make where either
  409.          * where with mfile concatenated, or if where hadn't been set we
  410.          * set it to mwhere with mfile concatenated.
  411.          * 
  412.          * If shorten is enabled and where hasn't been set yet, then where
  413.          * becomes mfile
  414.          */
  415.         if (!shorten)
  416.         {
  417.         if (where != NULL)
  418.             (void) sprintf (xwhere, "%s/%s", where, mfile);
  419.         else
  420.             (void) sprintf (xwhere, "%s/%s", mwhere, mfile);
  421.         where = xwhere;
  422.         }
  423.         else if (where == NULL)
  424.         where = mfile;
  425.     }
  426.     else
  427.     {
  428.         int i;
  429.  
  430.         /*
  431.          * The portion of a module was a file, so kludge up argv to be
  432.          * correct
  433.          */
  434.         for (i = 1; i < *pargc; i++)/* free the old ones */
  435.         free (argv[i]);
  436.         argv[1] = xstrdup (mfile);    /* set up the new one */
  437.         *pargc = 2;
  438.  
  439.         /* where gets mwhere if where isn't set */
  440.         if (where == NULL)
  441.         where = mwhere;
  442.     }
  443.     }
  444.  
  445.     /*
  446.      * if shorten is enabled and where isn't specified yet, we pluck the last
  447.      * directory component of argv[0] and make it the where
  448.      */
  449.     if (shorten && where == NULL)
  450.     {
  451.     if ((cp = rindex (argv[0], '/')) != NULL)
  452.     {
  453.         (void) strcpy (xwhere, cp + 1);
  454.         where = xwhere;
  455.     }
  456.     }
  457.  
  458.     /* if where is still NULL, use mwhere if set or the argv[0] dir */
  459.     if (where == NULL)
  460.     {
  461.     if (mwhere)
  462.         where = mwhere;
  463.     else
  464.     {
  465.         (void) strcpy (xwhere, argv[0]);
  466.         where = xwhere;
  467.     }
  468.     }
  469.  
  470.     if (preload_update_dir != NULL)
  471.     {
  472.     char tmp[PATH_MAX];
  473.  
  474.     (void) sprintf (tmp, "%s/%s", preload_update_dir, where);
  475.     free (preload_update_dir);
  476.     preload_update_dir = xstrdup (tmp);
  477.     }
  478.     else
  479.     preload_update_dir = xstrdup (where);
  480.  
  481.     /*
  482.      * At this point, where is the directory we want to build, repository is
  483.      * the repository for the lowest level of the path.
  484.      */
  485.  
  486.     /*
  487.      * If we are sending everything to stdout, we can skip a whole bunch of
  488.      * work from here
  489.      */
  490.     if (!pipeout)
  491.     {
  492.  
  493.     /*
  494.      * We need to tell build_dirs not only the path we want it to build,
  495.      * but also the repositories we want it to populate the path with. To
  496.      * accomplish this, we pass build_dirs a ``real path'' with valid
  497.      * repositories and a string to pre-pend based on how many path
  498.      * elements exist in where. Big Black Magic
  499.      */
  500.     prepath = xstrdup (repository);
  501.     cp = rindex (where, '/');
  502.     cp2 = rindex (prepath, '/');
  503.     while (cp != NULL)
  504.     {
  505.         cp = findslash (where, cp - 1);
  506.         cp2 = findslash (prepath, cp2 - 1);
  507.     }
  508.     *cp2 = '\0';
  509.     realdirs = cp2 + 1;
  510.  
  511.     /*
  512.      * build dirs on the path if necessary and leave us in the bottom
  513.      * directory (where if where was specified) doesn't contain a CVS
  514.      * subdir yet, but all the others contain CVS and Entries.Static
  515.      * files
  516.      */
  517.     if (build_dirs_and_chdir (where, prepath, realdirs, *pargc <= 1) != 0)
  518.     {
  519.         error (0, 0, "ignoring module %s", omodule);
  520.         free (prepath);
  521.         free (preload_update_dir);
  522.         preload_update_dir = oldupdate;
  523.         return (1);
  524.     }
  525.  
  526.     /* clean up */
  527.     free (prepath);
  528.  
  529.     /* set up the repository (or make sure the old one matches) */
  530.     if (!isfile (CVSADM) && !isfile (OCVSADM))
  531.     {
  532.         FILE *fp;
  533.  
  534.         if (!noexec && *pargc > 1)
  535.         {
  536.         Create_Admin (".", repository, (char *) NULL, (char *) NULL);
  537.         fp = open_file (CVSADM_ENTSTAT, "w+");
  538.         if (fclose(fp) == EOF)
  539.             error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
  540.         }
  541.         else
  542.         Create_Admin (".", repository, tag, date);
  543.     }
  544.     else
  545.     {
  546.         char *repos;
  547.  
  548.         /* get the contents of the previously existing repository */
  549.         repos = Name_Repository ((char *) NULL, preload_update_dir);
  550.         if (strcmp (repository, repos) != 0)
  551.         {
  552.         error (0, 0, "existing repository %s does not match %s",
  553.                repos, repository);
  554.         error (0, 0, "ignoring module %s", omodule);
  555.         free (repos);
  556.         free (preload_update_dir);
  557.         preload_update_dir = oldupdate;
  558.         return (1);
  559.         }
  560.         free (repos);
  561.     }
  562.     }
  563.  
  564.     /*
  565.      * If we are going to be updating to stdout, we need to cd to the
  566.      * repository directory so the recursion processor can use the current
  567.      * directory as the place to find repository information
  568.      */
  569.     if (pipeout)
  570.     {
  571.     if (chdir (repository) < 0)
  572.     {
  573.         error (0, errno, "cannot chdir to %s", repository);
  574.         free (preload_update_dir);
  575.         preload_update_dir = oldupdate;
  576.         return (1);
  577.     }
  578.     which = W_REPOS;
  579.     }
  580.     else
  581.     which = W_LOCAL | W_REPOS;
  582.  
  583.     if (tag != NULL || date != NULL)
  584.     which |= W_ATTIC;
  585.  
  586.     /*
  587.      * if we are going to be recursive (building dirs), go ahead and call the
  588.      * update recursion processor.  We will be recursive unless either local
  589.      * only was specified, or we were passed arguments
  590.      */
  591.     if (!(local_specified || *pargc > 1))
  592.     {
  593.     if (strcmp (command_name, "export") != 0 && !pipeout)
  594.         history_write ('O', preload_update_dir, tag ? tag : date, where,
  595.                repository);
  596.     err += do_update (0, (char **) NULL, options, tag, date,
  597.               force_tag_match, 0 /* !local */ ,
  598.               1 /* update -d */ , aflag, checkout_prune_dirs,
  599.               pipeout, which, join_rev1, join_rev2,
  600.               preload_update_dir);
  601.     free (preload_update_dir);
  602.     preload_update_dir = oldupdate;
  603.     return (err);
  604.     }
  605.  
  606.     if (!pipeout)
  607.     {
  608.     int i;
  609.     List *entries;
  610.  
  611.     /* we are only doing files, so register them */
  612.     entries = ParseEntries (0);
  613.     for (i = 1; i < *pargc; i++)
  614.     {
  615.         char line[MAXLINELEN];
  616.         char *user;
  617.         Vers_TS *vers;
  618.  
  619.         user = argv[i];
  620.         vers = Version_TS (repository, options, tag, date, user,
  621.                    force_tag_match, 0, entries, (List *) NULL);
  622.         if (vers->ts_user == NULL)
  623.         {
  624.         (void) sprintf (line, "Initial %s", user);
  625.         Register (entries, user, vers->vn_rcs, line, vers->options,
  626.               vers->tag, vers->date);
  627.         }
  628.         freevers_ts (&vers);
  629.     }
  630.     dellist (&entries);
  631.     }
  632.  
  633.     /* Don't log "export", just regular "checkouts" */
  634.     if (strcmp (command_name, "export") != 0 && !pipeout)
  635.     history_write ('O', preload_update_dir, (tag ? tag : date), where,
  636.                repository);
  637.  
  638.     /* go ahead and call update now that everything is set */
  639.     err += do_update (*pargc - 1, argv + 1, options, tag, date,
  640.               force_tag_match, local_specified, 1 /* update -d */,
  641.               aflag, checkout_prune_dirs, pipeout, which, join_rev1,
  642.               join_rev2, preload_update_dir);
  643.     free (preload_update_dir);
  644.     preload_update_dir = oldupdate;
  645.     return (err);
  646. }
  647.  
  648. static char *
  649. findslash (start, p)
  650.     char *start;
  651.     char *p;
  652. {
  653.     while ((int) p >= (int) start && *p != '/')
  654.     p--;
  655.     if ((int) p < (int) start)
  656.     return (NULL);
  657.     else
  658.     return (p);
  659. }
  660.  
  661. /*
  662.  * build all the dirs along the path to dir with CVS subdirs with appropriate
  663.  * repositories and Entries.Static files
  664.  */
  665. static int
  666. build_dirs_and_chdir (dir, prepath, realdir, sticky)
  667.     char *dir;
  668.     char *prepath;
  669.     char *realdir;
  670.     int sticky;
  671. {
  672.     FILE *fp;
  673.     char repository[PATH_MAX];
  674.     char path[PATH_MAX];
  675.     char path2[PATH_MAX];
  676.     char *slash;
  677.     char *slash2;
  678.     char *cp;
  679.     char *cp2;
  680.  
  681.     (void) strcpy (path, dir);
  682.     (void) strcpy (path2, realdir);
  683.     for (cp = path, cp2 = path2;
  684.     (slash = index (cp, '/')) != NULL && (slash2 = index (cp2, '/')) != NULL;
  685.      cp = slash + 1, cp2 = slash2 + 1)
  686.     {
  687.     *slash = '\0';
  688.     *slash2 = '\0';
  689.     (void) mkdir (cp, 0777);
  690.     if (chdir (cp) < 0)
  691.     {
  692.         error (0, errno, "cannot chdir to %s", cp);
  693.         return (1);
  694.     }
  695.     if (!isfile (CVSADM) && !isfile (OCVSADM) &&
  696.         strcmp (command_name, "export") != 0)
  697.     {
  698.         (void) sprintf (repository, "%s/%s", prepath, path2);
  699.         Create_Admin (".", repository, sticky ? (char *) NULL : tag,
  700.               sticky ? (char *) NULL : date);
  701.         if (!noexec)
  702.         {
  703.         fp = open_file (CVSADM_ENTSTAT, "w+");
  704.         if (fclose(fp) == EOF)
  705.             error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
  706.         }
  707.     }
  708.     *slash = '/';
  709.     *slash2 = '/';
  710.     }
  711.     (void) mkdir (cp, 0777);
  712.     if (chdir (cp) < 0)
  713.     {
  714.     error (0, errno, "cannot chdir to %s", cp);
  715.     return (1);
  716.     }
  717.     return (0);
  718. }
  719.